#include "MapEditor.h"

using namespace Ogre;

MapEditor::MapEditor(Root *mRoot){
	this->mRoot=mRoot;

	mDirection = Vector3::ZERO;
	
	// set the rotation and move speed
    mRotate = 0.13;
    mMove = 250;

	mRaySceneQuery = 0;        
	mCurrentObject = NULL;
	addingObject = false;        
	ctrlDown=false;

}

MapEditor::~MapEditor(void){        
	mSceneMgr->destroyQuery(mRaySceneQuery);

}

void MapEditor::createScene()
{

	//mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "Default SceneManager");
	mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE,"Default SceneManager");


	mCamera = mSceneMgr->createCamera("PlayerCam"); 
	Viewport *vp = mRoot->getAutoCreatedWindow()->addViewport(mCamera );
    mCamera->setNearClipDistance(5);
//    mCamera->setCollisionEnabled(false);
//    mCamera->getRealCamera()->setQueryFlags(0);
	// Set camera look point

	createTerrain();
	mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));

    SceneNode *node;

    // create the light
    Light *light = mSceneMgr->createLight("Light1");
    light->setType(Light::LT_POINT);
    light->setPosition(Vector3(250, 150, 250));
    light->setDiffuseColour(ColourValue::White);
    light->setSpecularColour(ColourValue::White);

    // Create the scene node
    node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode1", Vector3(-400, 200, 400));
	node->setPosition(40, 100, 580);
	node->yaw(Degree(-45));


    // Create the pitch node
    node = node->createChildSceneNode("PitchNode1");
    node->attachObject(mCamera);

    // create the second camera node/pitch node
    node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode2", Vector3(0, 200, 400));
    node = node->createChildSceneNode("PitchNode2");

	// Populate the camera and scene manager containers
    mCamNode = mCamera->getParentSceneNode();
	
	mSceneMgr->setSkyBox(true, (Constants::instance()->getSkyBoxName()).c_str());
	
	mRaySceneQuery = mSceneMgr->createRayQuery(Ray());
}

void MapEditor::createTerrain(){

	
	// Fog
    // NB it's VERY important to set this before calling setWorldGeometry 
    // because the vertex program picked will be different

	mSceneMgr->setWorldGeometry("..\\..\\media\\terrain.cfg");
    // Infinite far plane?
    if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
    {
        mCamera->setFarClipDistance(0);
    }

    // Define the required skyplane
    Plane plane;
    // 5000 world units from the camera
    plane.d = 5000;
    // Above the camera, facing down
    plane.normal = -Vector3::UNIT_Y;
		
}

void MapEditor::toggleFog(){

    ColourValue fadeColour(0.93, 0.86, 0.76);
    mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
    //mWindow->getViewport(0)->setBackgroundColour(fadeColour);
}

void MapEditor::ctrlStateToggle(){
	/*
	int moving=ST_MOVING;
	int mstatic=ST_STATIC;
	if(ctrlDown){
		ctrlDown=false;
		CEGUI::MouseCursor::getSingletonPtr()->setVisible(true);
		Constants::instance()->setMouseState(moving);
	}
	else{
		CEGUI::MouseCursor::getSingletonPtr()->setVisible(false);
		Constants::instance()->setMouseState(mstatic);
		ctrlDown=true;
	}
	*/
}

void MapEditor::updateGraphics(const FrameEvent &evt){

	//if(!ctrlDown){	
		mCamera->getParentNode()->translate(mDirection * evt.timeSinceLastFrame, Node::TS_LOCAL);
	//}
	if(addingObject&&mCurrentObject){
		moveObject();
	}
}

void MapEditor::updateCam(const OIS::MouseEvent &evt){

	//if(ctrlDown){	
		mCamNode->yaw(Degree(-mRotate * evt.state.X.rel), Node::TS_WORLD);
		mCamNode->pitch(Degree(-mRotate * evt.state.Y.rel), Node::TS_LOCAL);
	//}
	if(addingObject&&mCurrentObject){
		mStateWidth=float(evt.state.width);
		mStateHeight=float(evt.state.height);
		
		moveObject();
	}
}

void MapEditor::mousePressed(const OIS::MouseEvent &evt){

	addingObject=false;
	int state;
	int adding=ST_ADDING;
	int selecting=ST_SELECTING;
	int edit=ST_EDIT;
	state=Constants::instance()->getState();
	if(state==adding){
					
		if(mCurrentObject)
			mCurrentObject->stopObject();
		ctrlStateToggle();
		Constants::instance()->setState(edit);
	}
	if(state==selecting){
					
			//mirar si hemos cogido a alguien y tal
		CEGUI::Point mousePos = CEGUI::MouseCursor::getSingleton().getPosition();
		Ray mouseRay = mCamera->getCameraToViewportRay(mousePos.d_x/float(evt.state.width),mousePos.d_y/float(evt.state.height));

		mRaySceneQuery->setRay(mouseRay);
		mRaySceneQuery->setSortByDistance(true);
		RaySceneQueryResult &result = mRaySceneQuery->execute();
		RaySceneQueryResult::iterator itr = result.begin( );

		// Get results, create a node/entity on the position
		if (itr != result.end() && itr->movable)
		{
			
			if(!mCurrentObject)
				delete mCurrentObject;
			mCurrentObject = new SceneObject( itr->movable->getParentSceneNode(),mCamera,mRaySceneQuery);
		
		}
		//Constants::instance()->setState(edit);
		Constants::instance()->setState(adding);
	}
}

void MapEditor::addModel(CEGUI::String path){

        // add the ninja
	std::string _path=path.c_str();
	int adding=ST_ADDING;

	std::string nodeName="Node"+Constants::instance()->getNum();

    SceneNode *node;
	node = mSceneMgr->getRootSceneNode()->createChildSceneNode(nodeName);
    Entity *ent = mSceneMgr->createEntity(nodeName, _path);
	node->attachObject(ent);
	node->showBoundingBox(true);
	addingObject=true;
	if(!mCurrentObject)
		delete mCurrentObject;
	mCurrentObject = new SceneObject(node,mCamera,mRaySceneQuery);
	ctrlStateToggle();
	Constants::instance()->setState(adding);
}

void MapEditor::moveObject(){

	mCurrentObject->moveObject();
	
}

void MapEditor::selectObject(){

	//mCurrentObject->moveObject();
	int selecting=ST_SELECTING;
	CEGUI::MouseCursor::getSingletonPtr()->setVisible(true);
	Constants::instance()->setState(selecting);
	
}

void MapEditor::startMovingObject(){

	selectObject();
	//mCurrentObject->moveObject();
	
}

void MapEditor::startScalingObject(){

	selectObject();
	//mCurrentObject->moveObject();
	
}

void MapEditor::startTranslatingObject(){

	selectObject();
	//mCurrentObject->moveObject();
	
}

void MapEditor::startRotatingObject(){

	selectObject();
	//mCurrentObject->moveObject();
	
}

void MapEditor::startDuplicatingObject(){

	selectObject();
	//mCurrentObject->moveObject();
	
}

void MapEditor::moveFw(){
	mDirection.z = -mMove;
}

void MapEditor::moveBk(){
	mDirection.z = mMove;
}

void MapEditor::moveLeft(){
	mDirection.x = -mMove;
}

void MapEditor::moveRight(){
	mDirection.x = mMove;
}

void MapEditor::moveDown(){
	mDirection.y = -mMove;
}

void MapEditor::moveUp(){
	mDirection.y = mMove;
}

void MapEditor::stopFw(){
	mDirection.z = 0;
}

void MapEditor::stopBk(){
	mDirection.z = 0;
}

void MapEditor::stopLeft(){
	mDirection.x = 0;
}

void MapEditor::stopRight(){
	mDirection.x = 0;
}

void MapEditor::stopDown(){
	mDirection.y = 0;
}

void MapEditor::stopUp(){
	mDirection.y = 0;
}
